package dev.pda.display.presentation.common

import com.google.gson.Gson
import dev.pda.display.App
import dev.pda.display.R
import dev.pda.display.data.common.entity.ErrorResponse
import dev.pda.display.data.common.exceptions.ApiException
import dev.pda.display.data.common.exceptions.HttpException
import dev.pda.display.data.common.exceptions.NetWorkException
import dev.pda.display.presentation.common.entity.BaseResponse
import io.reactivex.functions.Consumer
import retrofit2.Response
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.net.UnknownServiceException

abstract class CustomErrorConsumer : Consumer<Throwable> {

    override fun accept(throwable: Throwable) {
        accept(throwable)
    }

    private fun createIMException(throwable: Throwable): HttpException {
        val errorResponse = ErrorResponse()
        return if (throwable is UnknownHostException ||
            throwable is ConnectException ||
            throwable is SocketTimeoutException ||
            throwable is UnknownServiceException
        ) {
            errorResponse.message = App.instance.resources.getString(R.string.error_net_work)
            NetWorkException(errorResponse)
        } else {
            errorResponse.message =
                if (throwable.message == null || throwable.message == HttpException.UNKNOWN_ERROR) {
                    App.instance.resources.getString(R.string.error_server)
                } else {
                    throwable.message
                }
            if (throwable is retrofit2.HttpException) {
                errorResponse.code = throwable.code().toString()
            }
            if (throwable is retrofit2.HttpException && throwable.response() != null) {
                //cover errorBody.code and message
                convertResponseToErrorResponse(throwable.response()!!, errorResponse)
            }
            ApiException(errorResponse)
        }
    }

    private fun convertResponseToErrorResponse(
        response: Response<*>,
        errorResponse: ErrorResponse
    ) {
        try {
            val json = response.errorBody()?.string()
            val baseResponse = Gson().fromJson<BaseResponse<Unit>>(json, BaseResponse::class.java)
            baseResponse?.let {
                errorResponse.message = it.message
                errorResponse.code = it.code.toString()
            }
        } catch (e: Exception) {

        }
    }

    abstract fun accept(it: HttpException)
}